package com.juejin.www.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.juejin.www.dao.UserDao;
import com.juejin.www.model.DTO.Result;
import com.juejin.www.utils.JwtUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;


/**
 * @author Jacky
 */
@Slf4j
@Component
@Aspect
@Order(1)
public class PermissionAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private UserDao userDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Around("@annotation(perm)")
    public Object checkPermission(ProceedingJoinPoint joinPoint,Perm perm) throws Throwable{
        int count;
        String permission = perm.permission();
        String permKey = "permission:"+permission;
        String permCacheValue = stringRedisTemplate.opsForValue().get(permKey);
        Integer pid;
        if(permCacheValue!=null){
            pid= JSON.parseObject(permCacheValue,Integer.class);
        }else {
            pid = userDao.getPid(permission);
            stringRedisTemplate.opsForValue().set(permKey, JSONObject.toJSONString(pid));
        }
        String jwt = request.getHeader("token");
        if(StringUtils.hasLength(jwt)){
            Integer uid = JwtUtils.getIdByJWT(jwt);
            String roleKey = "role:"+uid;
            String roleCacheValue = stringRedisTemplate.opsForValue().get(roleKey);
            Integer rid;
            if(roleCacheValue!=null){
                rid= JSON.parseObject(roleCacheValue,Integer.class);
            }else {
                rid = userDao.getRole(uid);
                stringRedisTemplate.opsForValue().set(roleKey, JSONObject.toJSONString(rid));
            }
            count = userDao.hasPermission(rid, pid);
        }else {
            count = userDao.hasPermission(1,pid);
        }

        if(count==0){
            log.info("鉴权失败，返回无权限错误信息");
            Result error = Result.error("DONT_HAVE_PERMISSION");
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);
            return null;
        }
        //调用原始目标方法运行
        Object result = joinPoint.proceed();
        return result;
    }
}
